from django.shortcuts import render, redirect
from django.views import View
from django import http
from django.contrib.auth import login, logout
import re
from .models import User
from meiduo_mall.utils.response_code import RETCODE
from django_redis import get_redis_connection
from django.contrib.auth import authenticate
from django.contrib.auth.mixins import LoginRequiredMixin
import json
from celery_tasks.mail.tasks import send_user_email
from django.conf import settings
from meiduo_mall.utils import meiduo_signature
from . import contants


class RegisterView(View):
    def get(self, request):
        return render(request, 'register.html')

    def post(self, request):
        # 1.接收
        user_name = request.POST.get('user_name')
        pwd = request.POST.get('pwd')
        cpwd = request.POST.get('cpwd')
        phone = request.POST.get('phone')
        allow = request.POST.get('allow')
        sms_code_request = request.POST.get('msg_code')

        # 2.验证
        # 2.1非空
        if not all([user_name, pwd, cpwd, phone, allow, sms_code_request]):
            return http.HttpResponseBadRequest('参数不完整')
        # 2.2用户名
        if not re.match('^[a-zA-Z0-9_-]{5,20}$', user_name):
            return http.HttpResponseBadRequest('请输入5-20个字符的用户名')
        if User.objects.filter(username=user_name).count() > 0:
            return http.HttpResponseBadRequest('用户名已存在')
        # 2.3密码
        if not re.match('[0-9A-Za-z]{8,20}$', pwd):
            return http.HttpResponseBadRequest('请输入8-20位的密码')
        if pwd != cpwd:
            return http.HttpResponseBadRequest('两次密码不一致')
        # 2.4手机号
        if not re.match('^1[345789]\d{9}', phone):
            return http.HttpResponseBadRequest('您输入的手机号格式不正确')
        if User.objects.filter(mobile=phone).count() > 0:
            return http.HttpResponseBadRequest('手机号已存在')
        # 2.5短信验证码
        # 连接redis
        redis_cli = get_redis_connection('verify_code')
        # 读取短信验证码
        sms_code_redis = redis_cli.get('sms_' + phone)
        # 判断是否过期
        if not sms_code_redis:
            return http.HttpResponseBadRequest('短信验证已过期')
        # 强制立即过期
        redis_cli.delete('sms_' + phone)
        # 判断短信验证码是否正确
        if sms_code_redis.decode() != sms_code_request:
            return http.HttpResponseBadRequest('短信验证码错误')

        # 3.处理
        # 3.1创建用户对象，保存到表中，先将密码加密，再保存到表中
        # user = User.objects.create(username=user_name, password=pwd, mobile=phone)
        user = User.objects.create_user(username=user_name, password=pwd, mobile=phone)

        # 3.2状态保持
        # request.session['user_id']=user.id
        login(request, user)

        # 4.响应
        response = redirect('/')
        response.set_cookie('username', user.username, max_age=60 * 60 * 24 * 14)

        return response


class UsernameCountView(View):
    def get(self, request, username):
        # 接收
        # 验证
        # 处理：查询判断
        count = User.objects.filter(username=username).count()
        # 响应：如果是ajax请求，则返回json数据
        return http.JsonResponse({
            'code': RETCODE.OK,
            'errmsg': 'OK',
            'count': count
        })


class MobileCountView(View):
    def get(self, request, mobile):
        # 接收
        # 验证
        # 处理：查询统计
        count = User.objects.filter(mobile=mobile).count()

        # 响应
        return http.JsonResponse({
            'code': RETCODE.OK,
            'errmsg': 'OK',
            'count': count
        })


class LoginView(View):
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        # 接收
        username = request.POST.get('username')
        pwd = request.POST.get('pwd')

        # 接收重定向参数
        next_url = request.GET.get('next', '/')

        # 验证
        if not all([username, pwd]):
            return http.HttpResponseBadRequest('参数不完整')
        # 2.2用户名
        if not re.match('^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseBadRequest('请输入5-20个字符的用户名')
        # 2.3密码
        if not re.match('[0-9A-Za-z]{8,20}$', pwd):
            return http.HttpResponseBadRequest('请输入8-20位的密码')

        # 处理
        user = authenticate(username=username, password=pwd)
        if user is None:
            # 用户名或密码错误
            return render(request, 'login.html', {
                'loginerror': '用户名或密码错误'
            })
        else:
            # 登录成功，状态保持
            login(request, user)
            # 向cookie中输出用户名，用于在前端提示登录状态
            response = redirect(next_url)
            response.set_cookie('username', user.username, max_age=60 * 60 * 24 * 14)

            return response

            # 响应


class LogoutView(View):
    def get(self, request):
        # 删session
        logout(request)
        # 删cookie中的username
        response = redirect('/')
        response.delete_cookie('username')
        return response


class InfoView(LoginRequiredMixin, View):
    def get(self, request):
        # 判断是否登录
        # if request.user.is_authenticated:
        #     # 已登录
        #     return render(request, 'user_center_info.html')
        # else:
        #     # 未登录
        #     return redirect('/login/')

        # 获取当前登录的用户
        user = request.user
        context = {
            'username': user.username,
            'mobile': user.mobile,
            'email': user.email,
            'email_active': user.email_active
        }

        return render(request, 'user_center_info.html', context)


class EmailView(LoginRequiredMixin, View):
    def put(self, request):
        # 接收，以put方式发送的请求
        dict1 = json.loads(request.body.decode())
        email = dict1.get('email')

        # 验证
        if not all([email]):
            return http.JsonResponse({
                'code': RETCODE.PARAMERR,
                'errmsg': '没有邮箱参数'
            })
        if not re.match('^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return http.JsonResponse({
                'code': RETCODE.PARAMERR,
                'errmsg': '邮箱格式错误'
            })

        # 处理
        # 修改属性
        user = request.user
        user.email = email
        user.save()

        # 发邮件
        token = meiduo_signature.dumps({'user_id': user.id}, contants.EMAIL_EXPIRES)
        verify_url = settings.EMAIL_VERIFY_URL + '?token=%s' % token
        send_user_email.delay(email, verify_url)

        # 响应
        return http.JsonResponse({
            'code': RETCODE.OK,
            'errmsg': 'OK'
        })


class EmailVerifyView(View):
    def get(self, request):
        # 接收
        token = request.GET.get('token')

        # 验证
        dict1 = meiduo_signature.loadds(token, contants.EMAIL_EXPIRES)
        if dict1 is None:
            return http.HttpResponseBadRequest('激活信息无效，请重新发邮件')
        user_id = dict1.get('user_id')

        # 处理
        try:
            user = User.objects.get(pk=user_id)
        except:
            return http.HttpResponseBadRequest('激活信息无效')
        else:
            user.email_active = True
            user.save()

        # 响应
        return redirect('/info/')


class AddressView(LoginRequiredMixin, View):
    def get(self, request):
        return render(request, 'user_center_site.html')
